home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / amiga / bmake15.lzh / recipe.c < prev    next >
C/C++ Source or Header  |  1991-11-02  |  3KB  |  147 lines

  1. /*    recipe.c
  2.  *    (c) Copyright 1991 by Ben Eng, All Rights Reserved
  3.  *
  4.  */
  5.  
  6. #include <clib/exec_protos.h>
  7. #include <clib/dos_protos.h>
  8.  
  9. #include <string.h>
  10. #include <ctype.h>
  11.  
  12. #include "make.h"
  13. #include "depend.h"
  14. #include "cond.h"
  15.  
  16. static
  17. struct List Cstack =
  18. {
  19.     (struct Node *)&Cstack.lh_Tail,    /* lh_Head */
  20.     (struct Node *)NULL,            /* lh_Tail */
  21.     (struct Node *)&Cstack.lh_Head,    /* lh_TailPred */
  22.     (UBYTE)NT_USER,
  23.     (UBYTE)0
  24. };
  25.  
  26.  
  27. static int
  28. changedir( char *newdir )
  29. {
  30.     BPTR oldlock = 0L, newlock = 0L;
  31.  
  32.     while( isspace( *newdir )) newdir++;
  33.     newlock = ( *newdir ) ? Lock( newdir, MODE_OLDFILE ) : Global.oldcwd;
  34.     if( newlock ) {
  35.         oldlock = CurrentDir( newlock );
  36.         if( *newdir && !Global.oldcwd )
  37.             Global.oldcwd = oldlock; /* bug if oldlock is the root */
  38.         else UnLock( oldlock );
  39.         return( 0 );
  40.     }
  41.     logprintf( "Unable to Lock directory %s\n", newdir );    
  42.     return( 1 );
  43. }
  44.  
  45. static void
  46. echo_commandline( struct command *cmd, char *cline )
  47. {
  48.     if( !(cmd->flags & CF_NOECHO ) || Param.debug )
  49.         logprintf( "\t\x9b0;33m%s\x9bm\n", cline );
  50. }
  51.  
  52. /* execute the command List to make a target */
  53. int
  54. recipe( const char *goalname, struct List *cmdlist )
  55. {
  56.     char special_cmd[ 10 ];
  57.     struct command *cmd;
  58.     char *expansion = NULL;
  59.     char *next;
  60.     int retval = 0, state;
  61.  
  62.     if( !cmdlist )
  63.         return( 0 ); /* no command list */
  64.  
  65.     if( Param.touch_mode ) {
  66.         logprintf( "\ttouch(%s)\n", goalname );
  67.         if( !Param.pretend_mode )
  68.             touch( goalname );
  69.         return( 0 );
  70.     }
  71.  
  72.     expansion = (char *)malloc( Param.MaxLine );
  73.  
  74.     for( cmd = (struct command *) cmdlist->lh_Head;    cmd->node.ln_Succ;
  75.         cmd = cmd->node.ln_Succ ) {
  76.         if( next = cmd->cmd )
  77.             while( isspace( *next )) next++;
  78.         if( next && *next ) {
  79.  
  80.             /* handle variable assignment before macro expansion */
  81.             if( strchr( next, '=' )) {
  82.                 echo_commandline( cmd, next );
  83.                 if( retval = process_macroline( next ) ? 0 : 1 )
  84.                     break;
  85.                 continue;
  86.             }
  87.  
  88.             if( expand_macros( expansion, next, Param.MaxLine )) {
  89.                 logprintf( "Error expanding macros on commandline:\n"
  90.                     "\t%s\n", next );
  91.                 break;
  92.             };
  93.             next = expansion;
  94.             while( isspace( *next )) next++;
  95.  
  96.             next = parse_str( special_cmd, next, sizeof(special_cmd));
  97.             if( !stricmp( special_cmd, "if" )) {
  98.                 echo_commandline( cmd, expansion );
  99.                 if( retval = drctv_if( next, &Cstack ))
  100.                     break;
  101.                 continue;
  102.             }
  103.             else if( !stricmp( special_cmd, "else" )) {
  104.                 echo_commandline( cmd, expansion );
  105.                 if( retval = drctv_else( next, &Cstack ))
  106.                     break;
  107.                 continue;
  108.             }
  109.             else if( !stricmp( special_cmd, "endif" )) {
  110.                 echo_commandline( cmd, expansion );
  111.                 if( retval = drctv_endif( next, &Cstack ))
  112.                     break;
  113.                 continue;
  114.             }
  115.  
  116.             state = get_directive_state( &Cstack );
  117.             if( state == STATE_IF_F || state == STATE_EL_T )
  118.                 continue;
  119.  
  120.             echo_commandline( cmd, expansion );
  121.  
  122.             if( !stricmp( special_cmd, "cd" )) {
  123.                 if( retval = changedir( next ))
  124.                     break;
  125.                 continue;
  126.             }
  127.  
  128.             retval = (Param.pretend_mode ) ? 0 : xsystem( expansion );
  129.             if( retval ) {
  130.                 char *s = (cmd->flags & CF_IGNORE ) ? "(Ignored)" : "" ;
  131.                 logprintf( "command returned error %d %s\n", retval, s );
  132.                 if( cmd->flags & CF_IGNORE )
  133.                     retval = 0;
  134.                 else
  135.                     break;
  136.             }
  137.         }
  138.     }
  139.     if( !retval && get_directive_state( &Cstack )) {
  140.         logprintf( "Missing endif conditional command for %s\n", goalname );
  141.         retval = 1;
  142.     }
  143.     if( expansion )
  144.         free( expansion );
  145.     return( retval );
  146. }
  147.